/**
 * 
 */
package fr.toussna.dao;

import java.util.List;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.Assert;
import org.testng.annotations.Test;

import fr.toussna.entity.Article;
import fr.toussna.entity.Comment;
import fr.toussna.entity.DomainEntity;
import fr.toussna.entity.Member;
import fr.toussna.exception.ObjectNotFoundException;
import fr.toussna.utils.EntityFactory;

/**
 * Testing MemberDAO
 * 
 * @author My
 * 
 */
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
@Test(suiteName = "MemberDAOTestCase")
public class MemberDAOTestCase extends AbstractTestNGSpringContextTests {

	private static final Log	LOGGER	= LogFactory
	                                           .getLog(MemberDAOTestCase.class
	                                                   .getName());

	@Autowired
	@Qualifier("memberdao")
	private MemberDAO	     memberdao;

	@Autowired
	@Qualifier("entityfactory")
	private EntityFactory	 entityfactory;

	@Test
	public void insert() {
		LOGGER.info("insert - starting...");
		Member member = (Member) entityfactory.createDomainEntity("member");
		Number id = memberdao.insert(member);
		try {
			Assert.assertNotNull(id);
			Assert.assertEquals(member.getName(),
			        ((Member) memberdao.select(id)).getName());
			Assert.assertEquals(member.getEmail(),
			        ((Member) memberdao.select(id)).getEmail());
			Assert.assertEquals(member.getPassword(),
			        ((Member) memberdao.select(id)).getPassword());
			member.setId((Long) id);
			memberdao.delete(member);
		} catch (Exception e) {
		}
		LOGGER.info("insert - end.");
	}

	@Test
	public void select() {
		LOGGER.info("select - starting...");
		Member member = (Member) entityfactory.createDomainEntity("member");
		Member member2 = (Member) entityfactory.createDomainEntity("member");
		Number id = memberdao.insert(member);
		Number id2 = memberdao.insert(member2);
		try {
			Assert.assertNotNull(id);
			Assert.assertNotNull(id2);
			Assert.assertEquals(member.getName(),
			        ((Member) memberdao.select(id)).getName());
			Assert.assertEquals(member2.getName(),
			        ((Member) memberdao.select(id2)).getName());
			member.setId((Long) id);
			member2.setId((Long) id2);
			memberdao.delete(member);
			memberdao.delete(member2);
		} catch (Exception e) {
		}
		LOGGER.info("select - end.");
	}

	@Test
	public void update() {
		LOGGER.info("update - starting...");
		Member member = (Member) entityfactory.createDomainEntity("member");
		Number id = memberdao.insert(member);
		member.setId((Long) id);
		member.setName("updated");
		member.setEmail("updated");
		try {
			memberdao.update(member);
			Assert.assertEquals("updated",
			        ((Member) memberdao.select(id)).getName());
			Assert.assertEquals("updated",
			        ((Member) memberdao.select(id)).getEmail());
			memberdao.delete(member);
		} catch (Exception e) {
		}
		LOGGER.info("update - end.");
	}

	@Test(expectedExceptions = {ObjectNotFoundException.class })
	public void delete() throws ObjectNotFoundException {
		LOGGER.info("delete - starting...");
		Member member = (Member) entityfactory.createDomainEntity("member");
		Number id = memberdao.insert(member);
		member.setId((Long) id);
			memberdao.delete(member);
			memberdao.select(id);
		LOGGER.info("delete - end.");
	}

	@Test
	public void selectAll() {
		LOGGER.info("selectAll - starting...");
		Member member = (Member) entityfactory.createDomainEntity("member");
		Member member2 = (Member) entityfactory.createDomainEntity("member");
		Number id = memberdao.insert(member);
		Number id2 = memberdao.insert(member2);
		Assert.assertFalse(memberdao.selectAll().isEmpty());
		Assert.assertEquals(2, memberdao.selectAll().size());
		member.setId((Long) id);
		member2.setId((Long) id2);
		memberdao.delete(member);
		memberdao.delete(member2);
		LOGGER.info("selectAll - end.");
	}

	@Test
	public void selectByName() {
		LOGGER.info("selectByName - starting...");
		Member member = (Member) entityfactory.createDomainEntity("member");
		Number id = memberdao.insert(member);
		List<DomainEntity> listMem = memberdao.selectByKey(member.getName());
		// LOGGER.warn("==================="+member.getName());
		// LOGGER.warn("\n ==================="+ listMem.get(0) );
		Assert.assertEquals(member.getName(),
		        ((Member) listMem.get(0)).getName());
		member.setId((Long) id);
		memberdao.delete(member);
		LOGGER.info("selectByName - end.");
	}

	// ====================Cache Testing===============================

	@Test
	public void selectCachedElement() {
		LOGGER.info("selectCachedElement - starting...");
		Member member = (Member) entityfactory.createDomainEntity("member");
		Number id = memberdao.insert(member);
		member.setId((Long) id);
		memberdao.insertToCache(member);
		Assert.assertEquals(member.getName(),
		        ((Member) memberdao.selectCachedElement((Long) id, Member.class.getCanonicalName())).getName());
		memberdao.delete(member);
		LOGGER.info("selectCachedElement - end.");
	}

	@Test
	public void insertToCache() {
		LOGGER.info("insertToCache - starting...");
		Member member = (Member) entityfactory.createDomainEntity("member");
		Member member2 = (Member) entityfactory.createDomainEntity("member");
		Number id = memberdao.insert(member);
		Number id2 = memberdao.insert(member2);
		member.setId((Long) id);
		member2.setId((Long) id2);
		memberdao.insertToCache(member);
		memberdao.insertToCache(member2);
		Assert.assertEquals(member.getName(),
		        ((Member) memberdao.selectCachedElement((Long) id, Member.class.getCanonicalName())).getName());
		Assert.assertEquals(member2.getEmail(),
		        ((Member) memberdao.selectCachedElement((Long) id2, Member.class.getCanonicalName())).getEmail());
		memberdao.delete(member);
		memberdao.delete(member2);
		LOGGER.info("insertToCache - end.");
	}

}
